/*
   FieldVis - A Tool for Visualizing Astrophysical Magnetohydrodynamic Flow
   
   Copyright (C) 2006 - 2008     FieldVis Development Team
  
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
  
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
  
   You should have received a copy of the GNU General Public License along
   with this program; if not, write to the Free Software Foundation, Inc.,
   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

   File     : Vector3D.cpp
   Author   : Blayne Field
   
   Purpose  : Implementation file for the Vector3D class.  This class
              just holds a 3D vector
*/

#include "Vector3D.h"
#include "Point.h"


// scales the vector so it has length 1
void Vector3D::Normalize()
{
   float len = Norm();
   if (len != 0)
   {
      x /= len;
      y /= len;
      z /= len;
   }
}

float Vector3D::Norm() const
{
   return sqrt(Dot(*this));
}

Vector3D Vector3D::Cross(const Vector3D &rhs) const
{
   return(Vector3D(y * rhs.z - z * rhs.y, z * rhs.x - x * rhs.z, x * rhs.y - y * rhs.x));
}

float Vector3D::Dot(const Vector3D &rhs) const
{
   return(x * rhs.x + y * rhs.y + z * rhs.z);
}

// overloaded + operator
Vector3D Vector3D::operator+(const Vector3D toAdd)
{
   Vector3D temp(x + toAdd.x, y + toAdd.y, z + toAdd.z);
   return temp;
}

// overloaded - operator
Vector3D Vector3D::operator-(const Vector3D toSub)
{
   Vector3D temp(x - toSub.x, y - toSub.y, z - toSub.z);
   return temp;
}

// overloaded * operator
Vector3D Vector3D::operator*(float mult)
{
   Vector3D temp(x * mult, y * mult, z * mult);
   return temp;
}

// overloaded * operator
Vector3D Vector3D::operator/(float mult)
{
   Vector3D temp(x / mult, y / mult, z / mult);
   return temp;
}

// overloaded = operator
Vector3D & Vector3D::operator=(const Vector3D & toCopy)
{
   if (this != &toCopy)
   {
      x = toCopy.x;
      y = toCopy.y;
      z = toCopy.z;
   }

   return *this;
}

std::ostream & operator<<(std::ostream & out, Vector3D & v)
{
   out << v.GetX() << " " << v.GetY() << " " << v.GetZ() << std::endl;
   return out;
}

